#!/bin/bash
# This file is part of the jetson_stats package (https://github.com/rbonghi/jetson_stats or http://rnext.it).
# Copyright (c) 2019 Raffaello Bonghi.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

# Emulator for NVIDIA Jetson jetson_clock

usage()
{
    if [ "$1" != "" ]; then
        tput setaf 1
        echo "$1"
        tput sgr0
    fi
    
    echo "jetson_clock, EMULATOR of NVIDIA Jetsons"
    echo "Maximize jetson performance by setting static max frequency to CPU, GPU and EMC clocks."
    echo "Usage:"
    echo "$0 [options]"
    echo "options,"
    echo "   -h|--help        | This help"
    echo "   --show           | display current settings"
    echo "   --restore [file] | restore current settings to a file (default: ${HOME}/l4t_dfs.conf)"
    echo "   --store [file]   | store current settings to a file (default: ${HOME}/l4t_dfs.conf)"
    echo "run jetson_clocks.sh without any option to set static max frequency to CPU, GPU and EMC clocks."
}

show_tx2()
{
cat << EOF
SOC family:tegra186  Machine:quill
Online CPUs: 0,3-5
CPU Cluster Switching: Disabled
cpu0: Online=1 Governor=schedutil MinFreq=345600 MaxFreq=2035200 CurrentFreq=2035200 IdleStates: C1=1 c7=1 
cpu1: Online=0 Governor=schedutil MinFreq=345600 MaxFreq=2035200 CurrentFreq=1113600 IdleStates: C1=1 c6=1 c7=1 
cpu2: Online=0 Governor=schedutil MinFreq=345600 MaxFreq=2035200 CurrentFreq=1113600 IdleStates: C1=1 c6=1 c7=1 
cpu3: Online=1 Governor=schedutil MinFreq=345600 MaxFreq=2035200 CurrentFreq=1881600 IdleStates: C1=1 c7=1 
cpu4: Online=1 Governor=schedutil MinFreq=345600 MaxFreq=2035200 CurrentFreq=2035200 IdleStates: C1=1 c7=1 
cpu5: Online=1 Governor=schedutil MinFreq=345600 MaxFreq=2035200 CurrentFreq=2035200 IdleStates: C1=1 c7=1 
GPU MinFreq=114750000 MaxFreq=1134750000 CurrentFreq=114750000
EMC MinFreq=40800000 MaxFreq=1600000000 CurrentFreq=1600000000 FreqOverride=0
Fan: speed=0
NV Power Mode: MAXP_CORE_ARM
EOF
}

show_off()
{
cat << EOF
SOC family:TEST  Machine:TEST
Online CPUs: 0-3
CPU Cluster Switching: Disabled
cpu0: Online=1 Governor=schedutil MinFreq=102000 MaxFreq=1428000 CurrentFreq=100000 IdleStates: WFI=1 c7=1 
cpu1: Online=1 Governor=schedutil MinFreq=102000 MaxFreq=1428000 CurrentFreq=100000 IdleStates: WFI=1 c7=1 c6=1 c8=1
cpu2: Online=1 Governor=schedutil MinFreq=102000 MaxFreq=1428000 CurrentFreq=100000 IdleStates: WFI=1 c7=1 
cpu3: Online=1 Governor=schedutil MinFreq=102000 MaxFreq=1428000 CurrentFreq=100000 IdleStates: WFI=1 c7=1 
cpu4: Online=1 Governor=schedutil MinFreq=102000 MaxFreq=1428000 CurrentFreq=100000 IdleStates: WFI=1 c7=1 
cpu5: Online=1 Governor=schedutil MinFreq=102000 MaxFreq=1428000 CurrentFreq=100000 IdleStates: WFI=1 c7=1 
GPU MinFreq=76800000 MaxFreq=921600000 CurrentFreq=100000
EMC MinFreq=204000000 MaxFreq=1600000000 CurrentFreq=1600000000 FreqOverride=0
Fan: speed=0
EOF
}


show_on()
{
cat << EOF
SOC family:TEST  Machine:TEST
Online CPUs: 0-3
CPU Cluster Switching: Disabled
cpu0: Online=1 Governor=schedutil MinFreq=1428000 MaxFreq=1428000 CurrentFreq=1428000 IdleStates: WFI=1
cpu1: Online=1 Governor=schedutil MinFreq=1428000 MaxFreq=1428000 CurrentFreq=1428000 IdleStates: WFI=1 c7=1 
cpu2: Online=1 Governor=schedutil MinFreq=1428000 MaxFreq=1428000 CurrentFreq=1428000 IdleStates: WFI=1 c7=1 C1=1
cpu3: Online=1 Governor=schedutil MinFreq=1428000 MaxFreq=1428000 CurrentFreq=1428000 IdleStates: WFI=1 c7=1
cpu4: Online=1 Governor=schedutil MinFreq=1428000 MaxFreq=1428000 CurrentFreq=1428000 IdleStates: WFI=1 c7=1
cpu5: Online=1 Governor=schedutil MinFreq=1428000 MaxFreq=1428000 CurrentFreq=1428000 IdleStates: WFI=1 c7=1
GPU MinFreq=921600000 MaxFreq=921600000 CurrentFreq=921600000
EMC MinFreq=204000000 MaxFreq=1600000000 CurrentFreq=1600000000 FreqOverride=0
Fan: speed=255
EOF
}

show()
{
    local modes=("MAXTEST" "TEST" "MINTEST" "MIN_MAX_TEST")
    local level=0
    # Load level from temp file
    if [ -f "/tmp/nvp_model_test" ] ; then
        level=$(cat /tmp/nvp_model_test)
    fi
    # Show status
    if [ -f "/tmp/jetson_clocks_test" ] ; then
        show_on
    else
        show_off
    fi
    echo "NV Power Mode: ${modes[level]}"
}

main()
{
    local TIME_SLEEP=1
    local conf=""
    local SHOW="False"
    local STORE="False"
    local RESTORE="False"
    # Decode all information from startup
    while [ -n "$1" ]; do
        case "$1" in
            --show)
                SHOW="True"
                ;;
            --restore)
                conf=$2
                RESTORE="True"
                shift 1
                ;;
            --store)
                conf=$2
                STORE="True"
                shift 1
                ;;
            -h|--help)
                usage
                exit 0
                ;;
            *)
                usage "[ERROR] Unknown option: $1"
                exit 1
            ;;
        esac
            shift 1
    done

    if [ $(id -u) -ne 0 ] ; then
        echo "Please run as root"
        exit 1
    fi

    # Go to sleep for an interval
    sleep $TIME_SLEEP

    # Run show message
    if [ "$SHOW" = "True" ] ; then
        # Show data
        show
        exit 0
    fi
    # Make a temporary file to show the status of the board
    if [ "$RESTORE" = "True" ] ; then
        if [ -f "/tmp/jetson_clocks_test" ] ; then
            # Remove fake test file
            rm "/tmp/jetson_clocks_test"
        fi
    elif [ "$STORE" = "True" ] ; then
        touch $conf
    else
        touch "/tmp/jetson_clocks_test"
    fi
}

main $@
exit 0

# EOF
